package com.quanyan.club.service.impl;

import com.alibaba.fastjson.JSON;
import com.quanyan.api.APIResponse;
import com.quanyan.club.constants.ClubConstants;
import com.quanyan.club.constants.ClubMemberPriorityConstants;
import com.quanyan.club.entity.RespClubBaseInfo;
import com.quanyan.club.entity.db.*;
import com.quanyan.club.mapper.*;
import com.quanyan.club.service.ClubDataService;
import com.quanyan.club.service.ClubMemberService;
import com.quanyan.common.constants.Constants;
import com.quanyan.common.exception.BizException;
import com.quanyan.common.http.HttpClientUtils;
import com.quanyan.common.utils.GsonUtils;
import com.quanyan.common.utils.StringUtil;
import com.quanyan.common.vo.resp.RespCity;
import com.quanyan.common.vo.resp.RespDistrict;
import com.quanyan.im.entity.req.ReqAddOrDelGroupMember;
import com.quanyan.im.entity.resp.RespIMGroup;
import com.quanyan.search.entity.vo.ClubIndexInfo;
import com.quanyan.search.service.impl.ClubSearchServiceImpl;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import scala.Int;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by zhuo.shi on 2016/8/31.
 */
@Service
public class ClubDataServiceImpl extends BaseServiceImpl implements ClubDataService{

    private static Logger logger = LoggerFactory.getLogger(ClubDataServiceImpl.class);

    @Autowired
    private TbClubMapper clubMapper;
    @Autowired
    private TbClubMemberMapper clubMemberMapper;
    @Autowired
    private TbClubMemberApplyMapper clubMemberApplyMapper;
    @Autowired
    private ClubMemberService clubMemberService;
    @Autowired
    private TbClubOnlineAccountMapper clubOnlineAccountMapper;
    @Autowired
    private TbClubOfflineAccountMapper clubOfflineAccountMapper;
    @Autowired
    private StationMasterMapper stationMasterMapper;
    @Autowired
    private StationUserRelationMapper stationUserRelationMapper;
    private ClubSearchServiceImpl clubSearchService;
    @PostConstruct
    protected  void init(){
        clubSearchService = new ClubSearchServiceImpl(searchCloudUrl);
    }

    @Autowired
    private TbClubSystemLogoMapper clubSystemLogoMapper;

    @Transactional
    private void migrateClubStation(StationMaster master) {
        logger.warn("开始生成达人：" + JSON.toJSONString(master) + "，的俱乐部。");

        TbClubExample example = new TbClubExample();
        example.createCriteria().andUidEqualTo(master.getUid());
        if (clubMapper.countByExample(example) > 0){
            logger.warn("达人"+master.getName()+"uid=" + master.getUid() + "已经导入创建了俱乐部。");
            return;
        }

        if (StringUtil.isBlankOrNull(master.getCityIds())){
            logger.warn("达人"+master.getName()+"uid=" + master.getUid() +"没有cityIds");
            return;
        }
        if (StringUtil.isBlankOrNull(master.getCagetoryIds())){
            logger.warn("达人"+master.getName()+"uid=" + master.getUid() +"没有cagetoryIds");
            return;
        }

        TbClub club = new TbClub();

        int cityId = Integer.valueOf(master.getCityIds().substring(0, 1));
        int fouderUid = master.getUid();
        String phone = master.getMobile();
        RespCity city = getCity(cityId);
        StringBuilder clubName = new StringBuilder();
        if (!StringUtil.isBlankOrNull(master.getName())){
            clubName.append(master.getName());
        }
        //达人活动地区+手机尾号后四位+运动类型+俱乐部（例：深圳0321羽毛球俱乐部）；
        if (city != null){
            clubName.append(city.getName());
        }
        if (!StringUtil.isBlankOrNull(phone) && phone.length() >=4){
            clubName.append(phone.substring(phone.length()-4, phone.length()));
        }
        int categoryId = Integer.valueOf(master.getCagetoryIds().substring(0, 1));
        TbClubType clubType = getClubType(categoryId);
        if (clubType != null) {
            clubName.append(clubType.getClubTypeName());
            club.setSportName(clubType.getClubTypeName());
            club.setBgUrl(clubType.getBgUrl());
            if (clubType.getCategoryId() == 3) {
                club.setClubPropertyId(1);
                club.setClubPropertyChildId(18);
            }
        }
        clubName.append("俱乐部");

        String logoUrl = master.getBackgroundImg();
        if (StringUtil.isBlankOrNull(logoUrl)){
            logoUrl = master.getIcon();
        }
        if (StringUtil.isBlankOrNull(logoUrl)){
            logoUrl = clubSystemLogoMapper.selectByPrimaryKey(1).getLogoUrl();
        }
        club.setLogoUrl(logoUrl);
        club.setClubName(clubName.toString());
        club.setClubType(categoryId);
        club.setFoundDate(new Date());
        club.setUid(master.getUid());
        club.setCityId(cityId);
        club.setFounderNickname(master.getNick());

        List<TbDistrict> districtList = getDistrictList(cityId);
        if (districtList != null && districtList.size() > 0){
            club.setDistrictId(districtList.get(0).getId());
        }
        club.setResidentPlaceId(34640);     //默认场馆
        club.setResidentPlaceName("百灵鸟");
        club.setIntroduce("");
        club.setPurpose("");
        club.setGuestTeamColor("");
        club.setHomeTeamColor("");
        club.setJoinType((byte)0);

        int ret = clubMapper.insertSelective(club);
        if (ret == 1) {
            int clubId = club.getId();

            //生成俱乐部线上账户
            TbClubOnlineAccount onlineAccount = new TbClubOnlineAccount();
            onlineAccount.setClubId(clubId);
            onlineAccount.setMoneyTotal(BigDecimal.ZERO);
            onlineAccount.setMoneyFreeze(BigDecimal.ZERO);
            onlineAccount.setMoneyUsable(BigDecimal.ZERO);
            onlineAccount.setIsDelete(Constants.IS_DELETE_FALSE);
            clubOnlineAccountMapper.insertSelective(onlineAccount);
            //生成俱乐部线下账户
            TbClubOfflineAccount offlineAccount = new TbClubOfflineAccount();
            offlineAccount.setClubId(clubId);
            offlineAccount.setMoneyTotal(BigDecimal.ZERO);
            offlineAccount.setIsDelete(Constants.IS_DELETE_FALSE);
            clubOfflineAccountMapper.insertSelective(offlineAccount);

            addClubInfo2SearchCloud(club);

            //将管理员加入到俱乐部成员表，并设置角色为主席
            addClubMember(null, clubId, fouderUid, Constants.ClubRole.CLUB_ROLE_PRESIDENT, "主席",
                    ClubMemberPriorityConstants.ROLE_CLUB_PRESIDENT_PRIORITY);

            logger.warn("创建达人" + master.getUid() + master.getName() + "的俱乐部[" + clubName + "] 成功！clubId="+clubId);
        }else {
            throw new BizException("创建达人俱乐部失败！");
        }
    }

    private void addClubInfo2SearchCloud(TbClub clubBaseInfo){
        ClubIndexInfo indexInfo = new ClubIndexInfo();
        indexInfo.setClub_id(String.valueOf(clubBaseInfo.getId()));
        indexInfo.setClub_name(clubBaseInfo.getClubName());
        RespCity city1 = getCity(clubBaseInfo.getCityId());
        if (city1 != null) {
            indexInfo.setClub_city_id(clubBaseInfo.getCityId());
            indexInfo.setClub_city_name(city1.getName());
        }
        RespDistrict district = getDistrict(clubBaseInfo.getDistrictId());
        if (district != null){
            indexInfo.setClub_district_id(district.getId());
            indexInfo.setClub_district_name(district.getName());
        }
        indexInfo.setClub_logo(clubBaseInfo.getLogoUrl());
        indexInfo.setClub_founder_nickname(clubBaseInfo.getFounderNickname());
        indexInfo.setClub_founder_uid(clubBaseInfo.getUid());
        indexInfo.setClub_sport_name(clubBaseInfo.getSportName());
        indexInfo.setClub_star(clubBaseInfo.getStar()==null?0d:clubBaseInfo.getStar());
        indexInfo.setClub_integral(clubBaseInfo.getIntegral()==null?0:clubBaseInfo.getIntegral());
        indexInfo.setClub_level(clubBaseInfo.getLevel()==null?0:clubBaseInfo.getLevel());
        indexInfo.setClub_type_id(clubBaseInfo.getClubType());
        indexInfo.setResident_place_id(clubBaseInfo.getResidentPlaceId());

        APIResponse response = clubSearchService.insertDoc(indexInfo);
        if (response == null || !response.isRet()){
            logger.warn("添加俱乐部索引失败：{}", JSON.toJSON(response));
            logger.warn("club index info:" + JSON.toJSONString(clubBaseInfo));
        }else {
            logger.debug("添加俱乐部clubId={}索引成功", clubBaseInfo.getId());
        }
    }
    private void migrateClubStationUser(StationUserRelation relation) {
        int uid = relation.getUid();
        TbClubExample example = new TbClubExample();
        example.createCriteria().andUidEqualTo(relation.getStationMasterUid());
        List<TbClub> clubList = clubMapper.selectByExample(example);
        if (clubList == null || clubList.size() == 0){
            logger.warn("达人"+relation.getUid() + "还没导入俱乐部！跳过");
            return;
        }
        int clubId = clubList.get(0).getId();
        addClubMember(clubList.get(0).getUid(), clubId, uid, Constants.ClubRole.ROLE_CLUB_MEMBER, "普通成员",
                ClubMemberPriorityConstants.ROLE_CLUB_MEMBER_PRIORITY);
    }

    @Transactional
    private void addClubMember(Integer fuid, int clubId, int uid, String roleCode, String roleName, int priority){

        gz(fuid, uid);

        TbClubMemberExample example = new TbClubMemberExample();
        example.createCriteria().andClubIdEqualTo(clubId).andUidEqualTo(uid).andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        if (clubMemberMapper.countByExample(example) > 0){
            logger.warn("成员：" + uid + "已经添加到俱乐部"+ clubId + "！跳过");
            return;
        }

        if (fuid != null) {
            TbClubMemberApply tbClubMemberApply = new TbClubMemberApply();
            tbClubMemberApply.setClubId(clubId);
            tbClubMemberApply.setUid(uid);
            tbClubMemberApply.setApplyType(ClubConstants.APPLY_TYPE_ASK);  //申请类别：申请
            tbClubMemberApply.setIsAuditing(ClubConstants.AUDITING_YES); //需要审核
            tbClubMemberApply.setStatus((byte) 1);   //审核通过
            tbClubMemberApply.setRemark("1.0版本迁移用户");
            clubMemberApplyMapper.insertSelective(tbClubMemberApply);
        }
        TbClubMember clubMember = new TbClubMember();
        clubMember.setClubId(clubId);
        clubMember.setUid(uid);
        clubMember.setIsTeamMember(Constants.NO);
        clubMember.setRoleCode(roleCode);
        clubMember.setRoleName(roleName);
        clubMember.setPriority(priority);
        clubMemberMapper.insertSelective(clubMember);

        clubMemberService.initClubMemberAccount(clubId, uid); //初始化账户
        //clubMemberService.insertClubMemberIndex(clubId, uid); //添加到搜索引擎

        logger.warn("添加成员：" + uid + "到俱乐部"+ clubId + "成功！");

    }

    @Value("${im.service.baseurl}")
    String url;

    private void gz(Integer uid, int friendId){
        if (uid == null){
            return;
        }
        Map<String, Object> kmap = new HashMap<>();
        kmap.put("ver","1.0");
        kmap.put("protocol_ver",1);
        kmap.put("add",uid);
        kmap.put("currentUid",friendId);
        String s = JSON.toJSONString(kmap);
        try {
            String result = HttpClientUtils.postJson(url+"/followUser.api", s);
            logger.warn("---------达人关注：{}，返回：{}", s ,result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void loadClubFromV1() {

        StationMasterExample example = new StationMasterExample();
        List<StationMaster> resultList = stationMasterMapper.selectByExample(example);
        logger.warn("xxxxx-----------" + resultList.size() + "------------xxxxxxx");
        for (int j = 0; j < resultList.size(); j++) {
            StationMaster master = resultList.get(j);
            this.migrateClubStation(master);
            logger.warn("------------------------------------" + j);
        }

    }

    @Override
    public void loadClubMemberFromV1() {
        StationUserRelationExample example = new StationUserRelationExample();
        List<StationUserRelation> resultList = stationUserRelationMapper.selectByExample(example);
        for (int i = 0; i< resultList.size(); i++){
            logger.warn("-------------------------" + i);
            this.migrateClubStationUser(resultList.get(i));
        }

    }

    @Override
   public void loadClubMemberIM(){
       StationUserRelationExample example = new StationUserRelationExample();
       List<StationUserRelation> resultList = stationUserRelationMapper.selectByExample(example);
       for (int i = 0; i< resultList.size(); i++){
           logger.warn("-------------------------" + i);
           addIM(resultList.get(i));
       }
   }

    public void loadClubMemberIM2(){
        StationUserRelation s = new StationUserRelation();
        s.setUid(9034322);
        s.setStationMasterUid(25);
        addIM(s);
    }

    private void addIM(StationUserRelation relation){
        int uid = relation.getUid();
        TbClubExample example = new TbClubExample();
        example.createCriteria().andUidEqualTo(relation.getStationMasterUid());
        List<TbClub> clubList = clubMapper.selectByExample(example);
        if (clubList == null || clubList.size() == 0){
            logger.warn("达人"+relation.getUid() + "还没导入俱乐部！跳过");
            return;
        }
        TbClub club = clubList.get(0);
        if (StringUtil.isBlankOrNull(club.getImGroupid())){
            return;
        }

        ReqAddOrDelGroupMember req = new ReqAddOrDelGroupMember();
        req.setCurrentUid(club.getUid());
        req.setGroupid(club.getImGroupid());
        req.setMembers(Arrays.asList(uid));

        String serverUrl = url + "/addMembers.api";
        try {
            String result = HttpClientUtils.postJson(serverUrl, JSON.toJSONString(req));
            logger.warn("加入俱乐部成员到聊天组，请求：" + JSON.toJSONString(req)+ "，返回：" + result);
        } catch (Exception e) {
            logger.error("请求加入或删除俱乐部聊天室成员错误：" + e.getMessage());
        }
    }


    @Override
    @Transactional
    public void updateClubInfo2SearchCloud(int clubId){
        TbClub tbClub = clubMapper.selectByPrimaryKey(clubId);
        if (tbClub == null){
            return;
        }
        RespClubBaseInfo clubBaseInfo = convert2RespClubBaseInfo(tbClub);
        //先删除
        APIResponse response = clubSearchService.deleteDocById(tbClub.getId());
        if (!response.isRet()){
            //throw new BizException("删除俱乐部"+tbClub.getId()+"索引失败，"+ response.getErrmsg());
        }
        //添加俱乐部信息到solr cloud
        addClubInfo2SearchCloud(clubBaseInfo);
    }


    private RespClubBaseInfo convert2RespClubBaseInfo(TbClub tbClub){
        if (tbClub == null){
            return null;
        }
        RespClubBaseInfo clubBaseInfo = new RespClubBaseInfo();
        clubBaseInfo.setClubId(tbClub.getId());
        clubBaseInfo.setSportName(tbClub.getSportName());
        clubBaseInfo.setClubName(tbClub.getClubName());
        clubBaseInfo.setClubLogo(tbClub.getLogoUrl());
        clubBaseInfo.setCityId(tbClub.getCityId());
        clubBaseInfo.setCity(getCity(tbClub.getCityId()));
        clubBaseInfo.setDistrict(getDistrict(tbClub.getDistrictId()));
        clubBaseInfo.setClubType(tbClub.getClubType());
        clubBaseInfo.setResidentPlaceId(tbClub.getResidentPlaceId());
        clubBaseInfo.setUid(tbClub.getUid());

        clubBaseInfo.setUsername(tbClub.getFounderNickname());
        clubBaseInfo.setIntegral(tbClub.getIntegral());
        clubBaseInfo.setJoinType((int)tbClub.getJoinType());
        clubBaseInfo.setLevel(tbClub.getLevel());
        clubBaseInfo.setStar(tbClub.getStar());
        clubBaseInfo.setRanking(this.getClubRanking(tbClub, tbClub.getCityId()));

        clubBaseInfo.setMemberCount(clubMemberService.countClubMembers(tbClub.getId(), true));  //俱乐部成员人数

        clubBaseInfo.setChatgroupid(tbClub.getImGroupid());     //俱乐部聊天室id
        return clubBaseInfo;
    }

    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;

    private int getClubRanking(TbClub club, Integer cityId){
        Map<String, Object> paramMap = new HashMap<>();
        if (cityId != null && cityId != 0){
            paramMap.put("cityId", cityId);
        }
        Integer sportTypeId = club.getClubType();
        if (sportTypeId != null){
            paramMap.put("sportTypeId", sportTypeId);
        }
        List<RespClubBaseInfo> list = sqlSessionTemplate.selectList("selectClubRankingList", paramMap);
        if (list != null && list.size() > 0){
            for (RespClubBaseInfo clubBaseInfo : list){
                if (clubBaseInfo.getClubId().intValue() == club.getId()){
                    return clubBaseInfo.getRanking();
                }
            }
        }
        return 0;
    }

    private void addClubInfo2SearchCloud(RespClubBaseInfo clubBaseInfo){
        ClubIndexInfo indexInfo = new ClubIndexInfo();
        indexInfo.setClub_id(String.valueOf(clubBaseInfo.getClubId()));
        indexInfo.setClub_name(clubBaseInfo.getClubName());
        RespCity city = clubBaseInfo.getCity();
        if (city != null) {
            indexInfo.setClub_city_id(city.getId());
            indexInfo.setClub_city_name(city.getName());
        }
        RespDistrict district = clubBaseInfo.getDistrict();
        if (district != null){
            indexInfo.setClub_district_id(district.getId());
            indexInfo.setClub_district_name(district.getName());
        }
        indexInfo.setClub_logo(clubBaseInfo.getClubLogo());
        indexInfo.setClub_founder_nickname(clubBaseInfo.getUsername());
        indexInfo.setClub_founder_uid(clubBaseInfo.getUid());
        indexInfo.setClub_sport_name(clubBaseInfo.getSportName());
        indexInfo.setClub_star(clubBaseInfo.getStar()==null?0d:clubBaseInfo.getStar());
        indexInfo.setClub_integral(clubBaseInfo.getIntegral()==null?0:clubBaseInfo.getIntegral());
        indexInfo.setClub_level(clubBaseInfo.getLevel()==null?0:clubBaseInfo.getLevel());
        indexInfo.setClub_type_id(clubBaseInfo.getClubType());
        indexInfo.setResident_place_id(clubBaseInfo.getResidentPlaceId());

        APIResponse response = clubSearchService.insertDoc(indexInfo);
        if (response == null || !response.isRet()){
            logger.warn("添加俱乐部索引失败：{}", JSON.toJSON(response));
            logger.warn("club index info:" + JSON.toJSONString(clubBaseInfo));
        }else {
            logger.debug("添加俱乐部clubId={}索引成功", clubBaseInfo.getClubId());
        }
    }
}
